<script setup>
import { toRefs, ref, onMounted, onBeforeUnmount, reactive, h, markRaw } from 'vue';
import { useRoute } from 'vue-router';
import CompassIcon from '@/assets/images/base-map/compass-icon.png';
import IconMinusCircle from '@/assets/images/base-map/icon-minus-circle.png';
import IconPlusCircle from '@/assets/images/base-map/icon-plus-circle.png';
import JuanLianIcon from '@/assets/images/base-map/juanlian.png';
import LayerIcon from '@/assets/images/base-map/layer-icon.png';
import PositionIcon from '@/assets/images/base-map/position-icon.png';
import FenGeIcon from '@/assets/images/base-map/qeige.png';
import RulerIcon from '@/assets/images/base-map/ruler-icon.png';
import To3dIcon from '@/assets/images/base-map/to3d-icon.png';
import { useMapStore } from '@/stores';
import { DEFAULT_MAP_STATE } from '@/utils/map-helper';
import {
  MAP_2D_INIT,
  MapBoxFlyTo,
  MapBoxMagnifyZoom,
  MapBoxReduceZoom,
  mapTo3d,
  REMOVE_2D_MAP,
} from '@/utils/map-utils';
import { useMapScale } from '@/utils/useMapScale';
import MapAttribute from './MapAttribute/MapAttributeIndex.vue';
import MapBaseLayer from './MapBaseLayer/MapBaseLayerIndex.vue';
import MapBufferAnalysis from './MapBufferAnalysis/IndexBase.vue';
import MapCompare from './MapCompare/MapCompareIndex.vue';
import MapCoverAnalysis from './MapCoverAnalysis/MapCoverAnalysisIndex.vue';
import MapCutting from './MapCutting/MapCuttingIndex.vue';
import MapMeasure from './MapMeasure/MapMeasureIndex.vue';
import MapPoints from './MapPoints/MapPointsIndex.vue';
import MapAttributeQuery from './MapResultInfo/MapAttributeQuery.vue';
import MapQueryResultPolygon from './MapResultInfo/MapQueryResultPolygon.vue';
import MapTermingQuery from './MapTermingQuery/MapTermingQueryIndex.vue';
import MapThermalAnalysis from './MapThermalAnalysis/MapThermalAnalysisIndex.vue';
import SvgIconIndex from './SvgIconIndex.vue';

const props = defineProps({
  mapId: String,
  mapRoles: Array,
});
const { mapId, mapRoles } = toRefs(props);
let map2D = null;

const { scale } = useMapScale();
const mapStore = useMapStore();
const resultFeatures = ref({});

const route = useRoute();
const mapTools = ref([]);

let routeValue = route.query;

const mapZoom = ref(DEFAULT_MAP_STATE.zoom);
const showObject = reactive({
  isMeasure: false, //当前是否开启测量
  showLayer: false, //当前是否显示图层
  isCompare: false, //是否开启卷帘功能
  isCutting: false, //当前开启数据切割
  isAttribute: false, //是否开启属性查询
  isAnalysisShow: false, //是否开启分析
  isTerming: false, //是否开启条件查询功能
  isHeatMap: false, //是否开启热力图
  isCoverMap: false, //是否开启占地分析
  resultFeaturesShow: false, //是否显示属性查询结果(单数据)
  resultFeaturesPolygonShow: false, //是否显示属性查询结果(多数据)
  isBuffer: false, //缓冲区
});

// 属性查询
const MapAttributeBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '属性查询',

        onClick: () => handleChangeIsAttribute(!showObject.isAttribute),
      },
      [
        h(SvgIconIndex, {
          iconClass: '属性查询',
          size: '20',
          class: 'cursor-pointer',
          title: '属性查询',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 条件查询
const MapTermingBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '条件查询',

        onClick: () => handleChangeIsTerm(!showObject.isTerming),
      },
      [
        h(SvgIconIndex, {
          iconClass: '条件查询',
          size: '20',
          class: 'cursor-pointer',
          title: '条件查询',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};
// 热力图分析
const MapHeatBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '热力图分析',
        onClick: () => handleChangeIsHeatMap(!showObject.isHeatMap),
      },
      [
        h(SvgIconIndex, {
          iconClass: '热力图分析',
          size: '20',
          class: 'cursor-pointer',
          title: '热力图分析',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 占地分析
const MapCoverBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '占地分析',
        onClick: () => handleChangeIsCoverMap(!showObject.isCoverMap),
      },
      [
        h(SvgIconIndex, {
          iconClass: '占地分析',
          size: '20',
          class: 'cursor-pointer',
          title: '占地分析',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 缓冲区分析
const MapCHangeIsBufferBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item layer-item',
        title: '缓冲区分析',
        onClick: () => handleCHangeIsBuffer(),
      },
      [
        h(SvgIconIndex, {
          iconClass: '缓冲区分析',
          size: '20',
          class: 'cursor-pointer',
          title: '缓冲区分析',
          color: '#c9e2fa',
        }),
      ],
    );
  },
};

// 数据切割
const MapCuttingBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: '数据切割',
        onClick: () => handleChangeIsCutting(!showObject.isCutting),
      },
      [
        h('img', {
          src: FenGeIcon,
          alt: '数据切割',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};
// 卷帘
const MapCompareBtn = {
  render: () => {
    return h(
      'div',
      {
        class: 'tool-item',
        title: showObject.isCompare ? '关闭卷帘' : '开启卷帘',
        onClick: () => handleChangeIsCompare(),
      },
      [
        h('img', {
          src: JuanLianIcon,
          alt: '卷帘',
          style: {
            width: '3rem',
            height: '3rem',
          },
        }),
      ],
    );
  },
};

onMounted(() => {
  setTimeout(() => {
    if (!map2D) {
      map2D = MAP_2D_INIT(mapId.value);

      getMapRoles();
      //   放大缩小
      map2D.on('zoom', function () {
        mapZoom.value = map2D.getZoom().toFixed(0);
      });

      window.addEventListener('resize', resize2D);
    }
  }, 100);
});

const getMapRoles = () => {
  mapTools.value = [
    {
      role: '属性查询',
      component: markRaw(MapAttributeBtn),
    },
    {
      role: '条件查询',
      component: markRaw(MapTermingBtn),
    },
    {
      role: '热力图分析',
      component: markRaw(MapHeatBtn),
    },
    {
      role: '占地分析',
      component: markRaw(MapCoverBtn),
    },
    {
      role: '缓冲区分析',
      component: markRaw(MapCHangeIsBufferBtn),
    },
    {
      role: '数据切割',
      component: markRaw(MapCuttingBtn),
    },
    {
      role: '卷帘',
      component: markRaw(MapCompareBtn),
    },
  ];
};

function resize2D() {
  map2D?.resize();
}

//初始化视角
const initializationPerspective = () => {
  MapBoxFlyTo([DEFAULT_MAP_STATE.longitude, DEFAULT_MAP_STATE.latitude], DEFAULT_MAP_STATE.zoom);
};

// 切换三维
const handle3DMode = () => {
  mapTo3d(mapStore.mode);
};

// 测量
const handleChangeIsMeasure = () => {
  showObject.isMeasure = !showObject.isMeasure;

  if (showObject.showLayer) {
    showObject.showLayer = false;
  }

  showObject.isCutting = false;
  showObject.isAttribute = false;
};

// 设置想要设置的状态
const changeShowUtil = (targetKey, boolean) => {
  for (const key in showObject) {
    if (Object.hasOwnProperty.call(showObject, key)) {
      showObject[key] = boolean && key === targetKey;
    }
  }
};

// 缓冲区
const handleCHangeIsBuffer = () => {
  changeShowUtil('isBuffer', !showObject.isBuffer);
};

// 卷帘
const handleChangeIsCompare = () => {
  changeShowUtil('isCompare', !showObject.isCompare);
};

// 数据切割
const handleChangeIsCutting = (type) => {
  changeShowUtil('isCutting', type);
};

// 属性查询
const handleChangeIsAttribute = (type) => {
  changeShowUtil('isAttribute', type);
};

// 热力图分析
const handleChangeIsHeatMap = (type) => {
  changeShowUtil('isHeatMap', type);
};

// 占地分析
const handleChangeIsCoverMap = (type) => {
  changeShowUtil('isCoverMap', type);
};

// 条件查询
const handleChangeIsTerm = (type) => {
  changeShowUtil('isTerming', type);
};

// 底图
const handleChangeIsBaseLayer = () => {
  changeShowUtil('showLayer', !showObject.showLayer);
};

// 关闭属性查询窗口
const handleCloseQueryLayer = () => {
  resultFeatures.value = {};
  showObject.resultFeaturesShow = false;
  showObject.resultFeaturesPolygonShow = false;
};

// 获取相关属性数据
const handleQueryInfo = (item, checked_layer, type) => {
  if (type == '属性查询') {
    resultFeatures.value = item;

    setTimeout(() => {
      if (Object.keys(item)?.length) {
        checked_layer == 'spatial_point'
          ? (showObject.resultFeaturesShow = true)
          : checked_layer == 'spatial_polygon'
          ? (showObject.resultFeaturesPolygonShow = true)
          : '';
      } else {
        checked_layer == 'spatial_point'
          ? (showObject.resultFeaturesShow = false)
          : checked_layer == 'spatial_polygon'
          ? (showObject.resultFeaturesPolygonShow = false)
          : '';
      }
    }, 0);
  }
};

onBeforeUnmount(() => {
  mapStore.RESET();
  window.removeEventListener('resize', resize2D);
  REMOVE_2D_MAP();
  map2D = null;
});
</script>
<template>
  <div id="map-root" class="map-root relative h-full w-full">
    <!-- 放大缩小初始位置工具 -->
    <div :class="`map-tool-top right-15px`">
      <div class="tool-item" :title="'初始化视角'" @click="initializationPerspective">
        <img :src="CompassIcon" alt="初始化视角" />
      </div>
      <div class="tool-item" :title="'当前位置'" @click="initializationPerspective">
        <img :src="PositionIcon" alt="当前位置" />
      </div>
      <div class="tool-item-changesize">
        <img :title="'放大'" :src="IconPlusCircle" alt="放大" @click="MapBoxMagnifyZoom" />
        <div :title="'级别'">{{ mapZoom }}</div>
        <img :title="'缩小'" :src="IconMinusCircle" alt="缩小" @click="MapBoxReduceZoom" />
      </div>
    </div>
    <div :class="`map-tool-bottom right-15px`">
      <!-- 工具栏(权限)-->
      <div v-for="(tool, index) in mapTools" :key="index">
        <component :is="tool.component" v-if="mapRoles.includes(tool.role)" />
      </div>

      <!-- 工具栏(默认)-->
      <div class="tool-item" :title="showObject.isMeasure ? '关闭测量' : '开启测量'" @click="handleChangeIsMeasure">
        <img :src="RulerIcon" alt="测量" />
      </div>
      <div class="tool-item layer-item" :title="'图层'" @click="handleChangeIsBaseLayer">
        <img :src="LayerIcon" alt="图层" />
      </div>
      <div class="tool-item" title="二三维切换" @click="handle3DMode">
        <img :src="To3dIcon" alt="二三维切换" />
      </div>
    </div>

    <!-- 底图 -->
    <MapBaseLayer v-if="showObject.showLayer" @handle-change-is-base-layer="handleChangeIsBaseLayer" />
    <!-- 条件查询 -->
    <MapTermingQuery
      v-if="showObject.isTerming"
      :route-value="routeValue"
      :map-id="mapId"
      @terming-close="() => handleChangeIsTerm(false)"
    />
    <!-- 属性查询 -->
    <MapAttribute
      v-if="showObject.isAttribute"
      :route-value="routeValue"
      :map-id="mapId"
      :result-features="resultFeatures"
      @attribute-close="() => handleChangeIsAttribute(false)"
      @handle-query-info="handleQueryInfo"
    />

    <!-- 热力图分析 -->
    <MapThermalAnalysis
      v-if="showObject.isHeatMap"
      :route-value="routeValue"
      :map-id="mapId"
      @heat-map-close="() => handleChangeIsHeatMap(false)"
    />

    <!--占地分析 -->

    <MapCoverAnalysis
      v-if="showObject.isCoverMap"
      :route-value="routeValue"
      :map-id="mapId"
      @cover-map-close="() => handleChangeIsCoverMap(false)"
    />
    <!-- 缓冲区分析 -->
    <MapBufferAnalysis v-if="showObject.isBuffer" @close="handleCHangeIsBuffer" />
    <!-- 测量 -->
    <MapMeasure v-show="showObject.isMeasure" @handle-change-is-measure="handleChangeIsMeasure" />
    <!-- 卷帘 -->
    <MapCompare v-if="showObject.isCompare" :map-id="mapId" :route-value="routeValue" />

    <!-- 数据切割 -->
    <MapCutting
      v-if="showObject.isCutting"
      :map-id="mapId"
      :route-value="routeValue"
      @cutting-close="() => handleChangeIsCutting(false)"
    />
    <!-- 比例尺 -->
    <div :class="`scale-box left-15px`">
      <span>{{ scale }}</span>
      <div class="scale-border" />
    </div>
    <div :id="mapId" class="map relative h-full w-full"></div>
    <MapPoints />

    <!-- 属性查询结果 -->
    <MapAttributeQuery
      v-if="showObject.resultFeaturesShow"
      class="animate__backInDown"
      :result-features="resultFeatures"
      @handle-close-query-layer="handleCloseQueryLayer"
    />

    <!-- 空间查询 -->
    <MapQueryResultPolygon
      :polygon-show="showObject.resultFeaturesPolygonShow"
      :result-features="resultFeatures"
      @close-query-result-show="handleCloseQueryLayer"
    />
  </div>
</template>

<style scoped lang="scss">
.map-root {
  overflow: hidden;

  .map-tool-top {
    position: fixed;
    top: 100px;
    z-index: 20;
    transition: 1s;

    .tool-item-changesize {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-around;
      width: 48px;
      height: 110px;
      padding: 5px 0;
      background: rgba(0, 69, 93, 0.6) url('@assets/images/base-map/change-size-bg.png') no-repeat center / 100%;

      img {
        display: block;
        width: 20px;
        height: 20px;
        margin: 0 auto;
        cursor: pointer;
      }

      div {
        color: rgba(201, 226, 250, 1);
        font-size: 14px;
      }
    }
  }

  .map-tool-bottom {
    position: fixed;
    bottom: 10px;
    z-index: 20;
    transition: 1s;
  }

  .tool-item {
    width: 48px;
    height: 48px;
    margin-bottom: 10px;
    cursor: pointer;

    i {
      width: 48px;
      height: 48px;
    }

    img {
      display: block;
      width: 48px;
      height: 48px;
    }
  }

  .scale-box {
    position: fixed;
    bottom: 40px;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 102px;
    height: 30px;
    transition: 1s;

    span {
      color: #fff;
      font-weight: 400;
      font-size: 16px;
      line-height: 24px;
      text-align: center;
    }

    .scale-border {
      width: 102px;
      height: 6px;
      border-right: 2px solid rgb(0, 160, 233);
      border-bottom: 4px solid rgb(0, 160, 233);
      border-left: 2px solid rgb(0, 160, 233);
    }
  }

  .layer-item {
    display: flex;
    align-items: center;
    justify-content: center;
    background: url('@/assets/images/base-map/layer-icon-bg.png') no-repeat center/100%;

    img {
      display: block;
      width: 18px;
      height: 18px;
    }
  }
}
</style>
